all files / fc-er/ locator.js

67.44% Statements 87/129
43.01% Branches 40/93
76.92% Functions 20/26
86.73% Lines 85/98
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206                               43223× 43223×   43223×     30818× 30818×     1520×       1520× 1513×   1520×   1520× 1520×             1520× 1520× 1520× 1520×   1520× 1496×           30830×           30830× 12405×         12405×       30830× 30830×       1521×   1521×   1521× 1521× 1521× 1521×         1528×                 1520×                                         30830×   30830× 30817×     30830× 1476×     30830×         30830× 30830×   30830× 30830× 30830× 30830× 12406× 12406×     12406× 12406×     30830×                   12408×                        
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
 
function _defaults(obj, defaults) { var keys = Object.getOwnPropertyNames(defaults); for (var i = 0; i < keys.length; i++) { var key = keys[i]; var value = Object.getOwnPropertyDescriptor(defaults, key); if (value && value.configurable && obj[key] === undefined) { Object.defineProperty(obj, key, value); } } return obj; }
 
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
 
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
 
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : _defaults(subClass, superClass); }
 
Iif (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
 
define(function (require) {
    'use strict';
 
    var util = require('./util');
    var canUseDOM = require('./ExecutionEnvironment').canUseDOM;
    var EventTarget = require('fc-mini-event/EventTarget');
    var config = require('./config');
    var events = require('./events');
 
    var getLocation = function getLocation() {
        // Firefox下`location.hash`存在自动解码的情况,
        // 比如hash的值是**abc%3def**,
        // 在Firefox下获取会成为**abc=def**
        // 为了避免这一情况,需要从`location.href`中分解
        var index = global.location.href.indexOf('#');
        var urlHash = index === -1 ? '' : global.location.href.slice(index);
 
        return urlHash;
    };
 
    var forwardHash = function forwardHash(locator) {
        var urlHash = getLocation();
        locator.redirect(urlHash);
    };
 
    var _start = function _start(locator, firstTime) {
        Iif (!canUseDOM) {
            return;
        }
 
        if (locator.handler == null) {
            locator.handler = util.bind(forwardHash, null, locator);
        }
        var handler = locator.handler;
 
        Eif (global.addEventListener) {
            global.addEventListener('hashchange', handler, false);
        } else if ('onhashchange' in global && global.document && global.document.documentMode > 7) {
            global.attachEvent('onhashchange', handler);
        } else {
            locator.rollTimer = setInterval(handler, 100);
        }
 
        Eif (firstTime) {
            (function () {
                var abort = false;
                locator.startupAbort = function () {
                    abort = true;
                };
                Promise.resolve().then(function () {
                    !abort && handler();
                });
            })();
        }
    };
 
    var updateURL = function updateURL(locator, urlHash, options) {
        var changed = locator.currentLocation !== urlHash;
 
        // 存储当前信息
        //
        // Opera下,相同的hash重复写入会在历史堆栈中重复记录,
        // 需要再行与当前的hash比较
        if (canUseDOM && changed && getLocation() !== urlHash) {
            Iif (options.slient) {
                locator.stop();
                global.location.hash = urlHash;
                _start(locator, false);
            } else {
                global.location.hash = urlHash;
            }
        }
 
        locator.currentLocation = urlHash;
        return changed;
    };
 
    var Locator = function (_EventTarget) {
        _inherits(Locator, _EventTarget);
 
        function Locator() {
            _classCallCheck(this, Locator);
 
            var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Locator).call(this));
 
            _this.currentLocation = '';
            _this.rollTimer = 0;
            _this.startupAbort = null;
            return _this;
        }
 
        _createClass(Locator, [{
            key: 'setErContext',
            value: function setErContext(erContext) {
                this.erContext = erContext;
            }
        }, {
            key: 'getErContext',
            value: function getErContext() {
                return this.erContext;
            }
        }, {
            key: 'start',
            value: function start() {
                _start(this, true);
            }
        }, {
            key: 'stop',
            value: function stop() {
                Iif (!canUseDOM) {
                    return;
                }
 
                Iif (this.rollTimer) {
                    clearInterval(this.rollTimer);
                    this.rollTimer = null;
                }
 
                Eif (this.startupAbort) {
                    this.startupAbort();
                    this.startupAbort = null;
                }
 
                Eif (global.removeEventListener) {
                    global.removeEventListener('hashchange', this.handler, false);
                } else if ('onhashchange' in global && global.document && global.document.documentMode > 7) {
                    global.detachEvent('onhashchange', this.handler);
                }
            }
        }, {
            key: 'resolveURL',
            value: function resolveURL(urlHash) {
                urlHash = urlHash + '';
 
                if (urlHash.indexOf('#') === 0) {
                    urlHash = urlHash.slice(1);
                }
 
                if (!urlHash || urlHash === '/') {
                    urlHash = config.indexURL;
                }
 
                return urlHash;
            }
        }, {
            key: 'redirect',
            value: function redirect(urlHash, options) {
                options = options || {};
                urlHash = this.resolveURL(urlHash);
 
                var referrer = this.currentLocation;
                var isLocationChanged = updateURL(this, urlHash, options);
                var shouldPerformRedirect = isLocationChanged || options.force;
                if (shouldPerformRedirect) {
                    Eif (!options.silent) {
                        this.fire('redirect', { url: urlHash, referrer: referrer });
                    }
 
                    var eventBus = this.getEventBus();
                    eventBus && eventBus.fire('redirect', { url: urlHash, referrer: referrer });
                }
 
                return shouldPerformRedirect;
            }
        }, {
            key: 'reload',
            value: function reload() {
                Eif (this.currentLocation) {
                    this.redirect(this.currentLocation, { force: true });
                }
            }
        }, {
            key: 'getEventBus',
            value: function getEventBus() {
                return this.erContext && this.erContext.getEventBus();
            }
        }, {
            key: 'setEventBus',
            value: function setEventBus(eventBus) {
                this.erContext && this.erContext.setEventBus(eventBus);
            }
        }]);
 
        return Locator;
    }(EventTarget);
 
    var instance = new Locator();
    instance.Locator = Locator;
 
    return instance;
});
//# sourceMappingURL=data:application/json;base64,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a0IsS0FBSyxTQUFMLENBQWUsV0FBZixFQUFsQixDQURHOzs7O3dDQUlGLFVBQVU7QUFDbEIscUJBQUssU0FBTCxJQUFrQixLQUFLLFNBQUwsQ0FBZSxXQUFmLENBQTJCLFFBQTNCLENBQWxCLENBRGtCOzs7OztNQXZGSixhQS9FQTs7QUEyS3RCLFFBQU0sV0FBVyxJQUFJLE9BQUosRUFBWCxDQTNLZ0I7QUE0S3RCLGFBQVMsT0FBVCxHQUFtQixPQUFuQixDQTVLc0I7O0FBOEt0QixXQUFPLFFBQVAsQ0E5S3NCO0NBQW5CLENBQVAiLCJmaWxlIjoibG9jYXRvci5qcyIsInNvdXJjZXNDb250ZW50IjpbImlmICh0eXBlb2YgZGVmaW5lICE9PSAnZnVuY3Rpb24nKSB7dmFyIGRlZmluZSA9IHJlcXVpcmUoJ2FtZGVmaW5lJykobW9kdWxlKX1cblxuZGVmaW5lKGZ1bmN0aW9uIChyZXF1aXJlKSB7XG4gICAgJ3VzZSBzdHJpY3QnO1xuXG4gICAgY29uc3QgdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xuICAgIGNvbnN0IGNhblVzZURPTSA9IHJlcXVpcmUoJy4vRXhlY3V0aW9uRW52aXJvbm1lbnQnKS5jYW5Vc2VET007XG4gICAgY29uc3QgRXZlbnRUYXJnZXQgPSByZXF1aXJlKCdmYy1taW5pLWV2ZW50L0V2ZW50VGFyZ2V0Jyk7XG4gICAgY29uc3QgY29uZmlnID0gcmVxdWlyZSgnLi9jb25maWcnKTtcbiAgICBjb25zdCBldmVudHMgPSByZXF1aXJlKCcuL2V2ZW50cycpO1xuXG5cbiAgICBjb25zdCBnZXRMb2NhdGlvbiA9ICgpID0+IHtcbiAgICAgICAgLy8gRmlyZWZveOS4i2Bsb2NhdGlvbi5oYXNoYOWtmOWcqOiHquWKqOino+eggeeahOaDheWGte+8jFxuICAgICAgICAvLyDmr5TlpoJoYXNo55qE5YC85pivKiphYmMlM2RlZioq77yMXG4gICAgICAgIC8vIOWcqEZpcmVmb3jkuIvojrflj5bkvJrmiJDkuLoqKmFiYz1kZWYqKlxuICAgICAgICAvLyDkuLrkuobpgb/lhY3ov5nkuIDmg4XlhrXvvIzpnIDopoHku45gbG9jYXRpb24uaHJlZmDkuK3liIbop6NcbiAgICAgICAgY29uc3QgaW5kZXggPSBnbG9iYWwubG9jYXRpb24uaHJlZi5pbmRleE9mKCcjJyk7XG4gICAgICAgIGNvbnN0IHVybEhhc2ggPSBpbmRleCA9PT0gLTEgPyAnJyA6IGdsb2JhbC5sb2NhdGlvbi5ocmVmLnNsaWNlKGluZGV4KTtcblxuICAgICAgICByZXR1cm4gdXJsSGFzaDtcbiAgICB9O1xuXG4gICAgY29uc3QgZm9yd2FyZEhhc2ggPSAobG9jYXRvcikgPT4ge1xuICAgICAgICBjb25zdCB1cmxIYXNoID0gZ2V0TG9jYXRpb24oKTtcbiAgICAgICAgbG9jYXRvci5yZWRpcmVjdCh1cmxIYXNoKTtcbiAgICB9O1xuXG4gICAgY29uc3Qgc3RhcnQgPSAobG9jYXRvciwgZmlyc3RUaW1lKSA9PiB7XG4gICAgICAgIGlmICghY2FuVXNlRE9NKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAobG9jYXRvci5oYW5kbGVyID09IG51bGwpIHtcbiAgICAgICAgICAgIGxvY2F0b3IuaGFuZGxlciA9IHV0aWwuYmluZChmb3J3YXJkSGFzaCwgbnVsbCwgbG9jYXRvcik7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgaGFuZGxlciA9IGxvY2F0b3IuaGFuZGxlcjtcblxuICAgICAgICBpZiAoZ2xvYmFsLmFkZEV2ZW50TGlzdGVuZXIpIHtcbiAgICAgICAgICAgIGdsb2JhbC5hZGRFdmVudExpc3RlbmVyKCdoYXNoY2hhbmdlJywgaGFuZGxlciwgZmFsc2UpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCdvbmhhc2hjaGFuZ2UnIGluIGdsb2JhbCAmJiBnbG9iYWwuZG9jdW1lbnQgJiYgZ2xvYmFsLmRvY3VtZW50LmRvY3VtZW50TW9kZSA+IDcpIHtcbiAgICAgICAgICAgIGdsb2JhbC5hdHRhY2hFdmVudCgnb25oYXNoY2hhbmdlJywgaGFuZGxlcik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBsb2NhdG9yLnJvbGxUaW1lciA9IHNldEludGVydmFsKGhhbmRsZXIsIDEwMCk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoZmlyc3RUaW1lKSB7XG4gICAgICAgICAgICBsZXQgYWJvcnQgPSBmYWxzZTtcbiAgICAgICAgICAgIGxvY2F0b3Iuc3RhcnR1cEFib3J0ID0gKCkgPT4ge1xuICAgICAgICAgICAgICAgIGFib3J0ID0gdHJ1ZTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICAhYWJvcnQgJiYgaGFuZGxlcigpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgdXBkYXRlVVJMID0gKGxvY2F0b3IsIHVybEhhc2gsIG9wdGlvbnMpID0+IHtcbiAgICAgICAgY29uc3QgY2hhbmdlZCA9IGxvY2F0b3IuY3VycmVudExvY2F0aW9uICE9PSB1cmxIYXNoO1xuXG4gICAgICAgIC8vIOWtmOWCqOW9k+WJjeS/oeaBr1xuICAgICAgICAvL1xuICAgICAgICAvLyBPcGVyYeS4i++8jOebuOWQjOeahGhhc2jph43lpI3lhpnlhaXkvJrlnKjljoblj7LloIbmoIjkuK3ph43lpI3orrDlvZXvvIxcbiAgICAgICAgLy8g6ZyA6KaB5YaN6KGM5LiO5b2T5YmN55qEaGFzaOavlOi+g1xuICAgICAgICBpZiAoY2FuVXNlRE9NICYmIGNoYW5nZWQgJiYgZ2V0TG9jYXRpb24oKSAhPT0gdXJsSGFzaCkge1xuICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2xpZW50KSB7XG4gICAgICAgICAgICAgICAgbG9jYXRvci5zdG9wKCk7XG4gICAgICAgICAgICAgICAgZ2xvYmFsLmxvY2F0aW9uLmhhc2ggPSB1cmxIYXNoO1xuICAgICAgICAgICAgICAgIHN0YXJ0KGxvY2F0b3IsIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGdsb2JhbC5sb2NhdGlvbi5oYXNoID0gdXJsSGFzaDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxvY2F0b3IuY3VycmVudExvY2F0aW9uID0gdXJsSGFzaDtcbiAgICAgICAgcmV0dXJuIGNoYW5nZWQ7XG4gICAgfTtcblxuICAgIGNsYXNzIExvY2F0b3IgZXh0ZW5kcyBFdmVudFRhcmdldCB7XG4gICAgICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICAgICAgc3VwZXIoKTtcblxuICAgICAgICAgICAgdGhpcy5jdXJyZW50TG9jYXRpb24gPSAnJztcbiAgICAgICAgICAgIHRoaXMucm9sbFRpbWVyID0gMDtcbiAgICAgICAgICAgIHRoaXMuc3RhcnR1cEFib3J0ID0gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIHNldEVyQ29udGV4dChlckNvbnRleHQpIHtcbiAgICAgICAgICAgIHRoaXMuZXJDb250ZXh0ID0gZXJDb250ZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgZ2V0RXJDb250ZXh0KCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXJDb250ZXh0O1xuICAgICAgICB9XG5cbiAgICAgICAgc3RhcnQoKSB7XG4gICAgICAgICAgICBzdGFydCh0aGlzLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0b3AoKSB7XG4gICAgICAgICAgICBpZiAoIWNhblVzZURPTSkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMucm9sbFRpbWVyKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLnJvbGxUaW1lcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yb2xsVGltZXIgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5zdGFydHVwQWJvcnQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnN0YXJ0dXBBYm9ydCgpO1xuICAgICAgICAgICAgICAgIHRoaXMuc3RhcnR1cEFib3J0ID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGdsb2JhbC5yZW1vdmVFdmVudExpc3RlbmVyKSB7XG4gICAgICAgICAgICAgICAgZ2xvYmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2hhc2hjaGFuZ2UnLCB0aGlzLmhhbmRsZXIsIGZhbHNlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCdvbmhhc2hjaGFuZ2UnIGluIGdsb2JhbCAmJiBnbG9iYWwuZG9jdW1lbnQgJiYgZ2xvYmFsLmRvY3VtZW50LmRvY3VtZW50TW9kZSA+IDcpIHtcbiAgICAgICAgICAgICAgICBnbG9iYWwuZGV0YWNoRXZlbnQoJ29uaGFzaGNoYW5nZScsIHRoaXMuaGFuZGxlcik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXNvbHZlVVJMKHVybEhhc2gpIHtcbiAgICAgICAgICAgIHVybEhhc2ggPSB1cmxIYXNoICsgJyc7XG5cbiAgICAgICAgICAgIGlmICh1cmxIYXNoLmluZGV4T2YoJyMnKSA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHVybEhhc2ggPSB1cmxIYXNoLnNsaWNlKDEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIXVybEhhc2ggfHwgdXJsSGFzaCA9PT0gJy8nKSB7XG4gICAgICAgICAgICAgICAgdXJsSGFzaCA9IGNvbmZpZy5pbmRleFVSTDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHVybEhhc2g7XG4gICAgICAgIH1cblxuICAgICAgICByZWRpcmVjdCh1cmxIYXNoLCBvcHRpb25zKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICAgICAgICAgIHVybEhhc2ggPSB0aGlzLnJlc29sdmVVUkwodXJsSGFzaCk7XG5cbiAgICAgICAgICAgIGNvbnN0IHJlZmVycmVyID0gdGhpcy5jdXJyZW50TG9jYXRpb247XG4gICAgICAgICAgICBjb25zdCBpc0xvY2F0aW9uQ2hhbmdlZCA9IHVwZGF0ZVVSTCh0aGlzLCB1cmxIYXNoLCBvcHRpb25zKTtcbiAgICAgICAgICAgIGNvbnN0IHNob3VsZFBlcmZvcm1SZWRpcmVjdCA9IGlzTG9jYXRpb25DaGFuZ2VkIHx8IG9wdGlvbnMuZm9yY2U7XG4gICAgICAgICAgICBpZiAoc2hvdWxkUGVyZm9ybVJlZGlyZWN0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLnNpbGVudCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmZpcmUoJ3JlZGlyZWN0Jywge3VybDogdXJsSGFzaCwgcmVmZXJyZXJ9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjb25zdCBldmVudEJ1cyA9IHRoaXMuZ2V0RXZlbnRCdXMoKTtcbiAgICAgICAgICAgICAgICBldmVudEJ1cyAmJiBldmVudEJ1cy5maXJlKCdyZWRpcmVjdCcsIHt1cmw6IHVybEhhc2gsIHJlZmVycmVyfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBzaG91bGRQZXJmb3JtUmVkaXJlY3Q7XG4gICAgICAgIH1cblxuICAgICAgICByZWxvYWQoKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50TG9jYXRpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLnJlZGlyZWN0KHRoaXMuY3VycmVudExvY2F0aW9uLCB7Zm9yY2U6IHRydWV9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGdldEV2ZW50QnVzKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXJDb250ZXh0ICYmIHRoaXMuZXJDb250ZXh0LmdldEV2ZW50QnVzKCk7XG4gICAgICAgIH1cblxuICAgICAgICBzZXRFdmVudEJ1cyhldmVudEJ1cykge1xuICAgICAgICAgICAgdGhpcy5lckNvbnRleHQgJiYgdGhpcy5lckNvbnRleHQuc2V0RXZlbnRCdXMoZXZlbnRCdXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgaW5zdGFuY2UgPSBuZXcgTG9jYXRvcigpO1xuICAgIGluc3RhbmNlLkxvY2F0b3IgPSBMb2NhdG9yO1xuXG4gICAgcmV0dXJuIGluc3RhbmNlO1xufSk7XG4iXX0=